﻿
namespace Timo.Common.Extension;

/// <summary>
/// 文件操作帮助类
/// </summary>
public static class FileHelper
{
    /// <summary>
    /// 检查文件是否真实存在。
    /// </summary>
    /// <param name="path">文件全名（包括路径）。</param>
    /// <returns>Boolean</returns>
    public static bool IsExistFile(this string path)
    {
        try
        {
            return File.Exists(path);
        }
        catch
        { return false; }
    }

    /// <summary>
    /// 检查目录是否真实存在。
    /// </summary>
    /// <param name="path">目录路径.</param>
    /// <returns>Boolean</returns>
    public static bool IsExistDirectory(this string path)
    {
        try
        {
            return Directory.Exists(Path.GetDirectoryName(path));
        }
        catch
        { return false; }
    }
    /// <summary>
    /// 获取指定目录中所有文件列表
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>        
    public static string[] GetFileNames(this string directory_path)
    {
        //如果目录不存在，则抛出异常
        if (!IsExistDirectory(directory_path))
        {
            throw new FileNotFoundException();
        }

        //获取文件列表
        return Directory.GetFiles(directory_path);
    }

    /// <summary>
    /// 获取指定目录及子目录中所有文件列表
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>
    /// <param name="search_pattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
    /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
    /// <param name="isSearch_child">是否搜索子目录</param>
    public static string[] GetFileNames(this string directory_path, string search_pattern, bool isSearch_child)
    {
        //如果目录不存在，则抛出异常
        if (!IsExistDirectory(directory_path))
        {
            throw new FileNotFoundException();
        }

        try
        {
            if (isSearch_child)
            {
                return Directory.GetFiles(directory_path, search_pattern, SearchOption.AllDirectories);
            }
            else
            {
                return Directory.GetFiles(directory_path, search_pattern, SearchOption.TopDirectoryOnly);
            }
        }
        catch (IOException ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// 检测指定目录中是否存在指定的文件,若要搜索子目录请使用重载方法.
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>
    /// <param name="search_pattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
    /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>        
    public static bool Contains(this string directory_path, string search_pattern)
    {
        try
        {
            //获取指定的文件列表
            string[] fileNames = GetFileNames(directory_path, search_pattern, false);

            //判断指定文件是否存在
            if (fileNames.Length == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
            //LogHelper.WriteTraceLog(TraceLogLevel.Error, ex.Message);
        }
    }

    /// <summary>
    /// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>        
    public static string[] GetDirectories(this string directory_path)
    {
        try
        {
            return Directory.GetDirectories(directory_path);
        }
        catch (IOException ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// 获取指定目录及子目录中所有子目录列表
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>
    /// <param name="search_pattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
    /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
    /// <param name="is_search_child">是否搜索子目录</param>
    public static string[] GetDirectories(this string directory_path, string search_pattern, bool is_search_child)
    {
        try
        {
            if (is_search_child)
            {
                return Directory.GetDirectories(directory_path, search_pattern, SearchOption.AllDirectories);
            }
            else
            {
                return Directory.GetDirectories(directory_path, search_pattern, SearchOption.TopDirectoryOnly);
            }
        }
        catch (IOException ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// 检测指定目录是否为空
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>        
    public static bool IsEmptyDirectory(this string directory_path)
    {
        try
        {
            //判断是否存在文件
            string[] fileNames = GetFileNames(directory_path);
            if (fileNames.Length > 0)
            {
                return false;
            }

            //判断是否存在文件夹
            string[] directoryNames = GetDirectories(directory_path);
            if (directoryNames.Length > 0)
            {
                return false;
            }

            return true;
        }
        catch
        {
            //这里记录日志
            //LogHelper.WriteTraceLog(TraceLogLevel.Error, ex.Message);
            return true;
        }
    }

    #region 从文件的绝对路径中获取文件名( 不包含扩展名 )
    /// <summary>
    /// 从文件的绝对路径中获取文件名( 不包含扩展名 )
    /// </summary>
    /// <param name="file_path">文件的绝对路径</param>        
    public static string GetFileNameNoExtension(this string file_path)
    {
        if (string.IsNullOrEmpty(file_path) || string.IsNullOrWhiteSpace(file_path))
            return string.Empty;
        //获取文件的名称
        FileInfo fi = new FileInfo(file_path);
        return fi.Name.Split('.')[0];
    }
    #endregion

    #region 从文件的绝对路径中获取扩展名
    /// <summary>
    /// 从文件的绝对路径中获取扩展名
    /// </summary>
    /// <param name="file_path">文件的绝对路径</param>        
    public static string GetExtension(this string file_path)
    {
        if (string.IsNullOrEmpty(file_path) || string.IsNullOrWhiteSpace(file_path))
            return string.Empty;
        //获取文件的名称
        FileInfo fi = new FileInfo(file_path);
        return fi.Extension;
    }
    #endregion

    #region 删除指定目录
    /// <summary>
    /// 删除指定目录及其所有子目录
    /// </summary>
    /// <param name="directory_path">指定目录的绝对路径</param>
    public static void DeleteDirectory(this string directory_path)
    {
        if (IsExistDirectory(directory_path))
        {
            Directory.Delete(directory_path, true);
        }
    }
    #endregion


}
